package com.aso.common.utils;

import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Handler;
import android.os.Looper;
import android.os.PowerManager;
import android.view.KeyEvent;

import com.itsdf07.alog.ALog;


/**
 * @Description ：
 * @Author itsdf07
 * @Time 2018/1/22
 */

public class AudioUtils {
    private static final String TAG = "AudioUtils";

    /**
     * GEM doesn't have audio focus, and can't duck (play at a low volume)
     */
    private static final int AUDIO_NO_FOCUS_NO_DUCK = 0;
    /**
     * GEM doesn't have focus, but can duck (play at a low volume)
     */
    private static final int AUDIO_NO_FOCUS_CAN_DUCK = 1;
    /**
     * GEM has full audio focus
     */
    private static final int AUDIO_FOCUSED = 2;


    private static AudioUtils instance;
    private Context mContext;
    private AudioManager mAudioManager;
    private MediaPlayer mMediaPlayer;

    private int mRawRes = -1;

    private Handler mMainHandler = new Handler(Looper.getMainLooper());

    public static AudioUtils getInstance() {
        if (instance == null) {
            instance = new AudioUtils();
        }
        return instance;
    }

    public void init(Context context, int raw) {
        if (context == null) {
            new Throwable("AudioUtils 初始化失败:上下文参数为 null");
        }
        mRawRes = raw;
        this.mContext = context;
        mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
//        createMediaPlayerIfNeeded();
    }

    /**
     * Makes sure the media player exists and has been reset. This will create
     * the media player if needed, or reset the existing media player if one
     * already exists.
     */
    private void createMediaPlayerIfNeeded() {
        if (mMediaPlayer == null) {
            mMediaPlayer = MediaPlayer.create(mContext, mRawRes);

            // Make sure the media player will acquire a wake-lock while
            // playing. If we don't do that, the CPU might go to sleep while the
            // song is playing, causing playback to stop.
            mMediaPlayer.setWakeMode(mContext, PowerManager.PARTIAL_WAKE_LOCK);

            // we want the media player to notify us when it's ready preparing,
            // and when it's done playing:
            mMediaPlayer.setOnPreparedListener(mOnPreparedListener);
            mMediaPlayer.setOnCompletionListener(mOnCompletionListener);
            mMediaPlayer.setOnErrorListener(mOnErrorListener);
            mMediaPlayer.setOnSeekCompleteListener(mOnSeekCompleteListener);
        } else {
            mMediaPlayer.reset();
        }
    }

    /**
     * 开始播放
     */
    public void onPlay() {

        if (mMediaPlayer == null) {
            ALog.eTag(TAG, "MediaPlayer init failed");
            return;
        }
//        sendMediaButton(mContext, 127);
//        onRequestAudioFocus();
        onStop();
//        mMediaPlayer.seekTo(1);//设置播放的进度
        mMediaPlayer.start();
    }

    public void sendMediaButtonDelay(final Context context, final int keyCode, long delay) {
        mMainHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
                //先判断后台是否再播放音乐
                if (audioManager.isMusicActive()) {
                    KeyEvent keyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, keyCode);
                    Intent intent = new Intent(Intent.ACTION_MEDIA_BUTTON);
                    intent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
                    context.sendOrderedBroadcast(intent, null);

                    keyEvent = new KeyEvent(KeyEvent.ACTION_UP, keyCode);
                    intent = new Intent(Intent.ACTION_MEDIA_BUTTON);
                    intent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
                    context.sendOrderedBroadcast(intent, null);
                }
            }
        }, delay);
    }

    public void sendMediaButton(Context context, int keyCode) {
        sendMediaButtonDelay(context, keyCode, 0);
    }

    /**
     * 暂停播放
     */
    public void onPause() {
        if (mMediaPlayer == null) {
            ALog.eTag(TAG, "MediaPlayer init failed");
            return;
        }
        if (mMediaPlayer.isPlaying()) {
            mMediaPlayer.stop();
        }
    }

    /**
     * 结束播放
     */
    public void onStop() {
        if (mMediaPlayer == null) {
            ALog.eTag(TAG, "MediaPlayer init failed");
            return;
        }
        onPause();
        mMediaPlayer.reset();
    }

    /**
     * 申请媒体焦点
     */
    public void onRequestAudioFocus() {
        ALog.dTag(TAG, "onRequestAudioFocus");
        try {
            if (mAudioManager == null) {
                mAudioManager = (AudioManager) Utils.getApplication().getSystemService(Context.AUDIO_SERVICE);
            }
            int result = mAudioManager.requestAudioFocus(mOnAudioFocusChangeListener, AudioManager.STREAM_MUSIC,
                    AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
            ALog.dTag(TAG, "result = %s", result);
        } catch (Exception e) {
            ALog.eTag(TAG, "e = %s", e.toString());
        }

    }

    /**
     * 释放媒体焦点
     */
    public void onAbandonAudioFocus() {
        int result = mAudioManager.abandonAudioFocus(mOnAudioFocusChangeListener);
        ALog.dTag(TAG, "onAbandonAudioFocus:%s", result);

//        if (mAudioFocus == AUDIO_FOCUSED) {
//            if (mAudioManager.abandonAudioFocus(mOnAudioFocusChangeListener) == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
//                mAudioFocus = AUDIO_NO_FOCUS_NO_DUCK;
//            }
//        }
    }

    /**
     * 媒体焦点变化监听
     */
    private AudioManager.OnAudioFocusChangeListener mOnAudioFocusChangeListener = new AudioManager.OnAudioFocusChangeListener() {

        @Override
        public void onAudioFocusChange(int focusChange) {
            ALog.dTag(TAG, "focusChange = %s", focusChange);
            if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {
                // We have gained focus:

            } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS ||
                    focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT ||
                    focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK) {
                // We have lost focus. If we can duck (low playback volume), we can keep playing.
                // Otherwise, we need to pause the playback.

                // If we are playing, we need to reset media player by calling configMediaPlayerState
                // with mAudioFocus properly set.
            } else {
                ALog.eTag(TAG, "Ignoring unsupported focusChange: %s", focusChange);
            }
        }
    };

    /**
     * 媒体播放进度监听：比如播放完一段媒体之后回调onCompletion
     */
    private MediaPlayer.OnCompletionListener mOnCompletionListener = new MediaPlayer.OnCompletionListener() {

        @Override
        public void onCompletion(MediaPlayer mp) {
            ALog.dTag(TAG, "AudioSessionId = %s,isPlaying = %s,isLooping = %s", mp.getAudioSessionId(), mp.isPlaying(), mp.isLooping());
        }
    };

    /**
     * 媒体文件准备播放状态监听:准备好可以播放时调用onPrepared
     */
    private MediaPlayer.OnPreparedListener mOnPreparedListener = new MediaPlayer.OnPreparedListener() {

        @Override
        public void onPrepared(MediaPlayer mp) {
            ALog.dTag(TAG, "AudioSessionId = %s,isPlaying = %s,isLooping = %s", mp.getAudioSessionId(), mp.isPlaying(), mp.isLooping());
        }
    };

    private MediaPlayer.OnErrorListener mOnErrorListener = new MediaPlayer.OnErrorListener() {

        @Override
        public boolean onError(MediaPlayer mp, int what, int extra) {
            ALog.dTag(TAG, "AudioSessionId = %s,isPlaying = %s,isLooping = %s,what = %s,extra = %s", mp.getAudioSessionId(), mp.isPlaying(), mp.isLooping(), what, extra);
            return true;
        }
    };

    private MediaPlayer.OnSeekCompleteListener mOnSeekCompleteListener = new MediaPlayer.OnSeekCompleteListener() {

        @Override
        public void onSeekComplete(MediaPlayer mp) {
            ALog.dTag(TAG, "AudioSessionId = %s,isPlaying = %s,isLooping = %s", mp.getAudioSessionId(), mp.isPlaying(), mp.isLooping());
        }
    };

}
